package eg.ci.mvn.service.api.dict;

import cn.hutool.core.util.StrUtil;

import java.util.Arrays;
import java.util.List;

/**
 * <b>Description : </b> 用于存放数据字典的Bean
 *
 * @author CPF
 * @date 2019/12/13 10:43
 **/
public interface IDictItem {
    /**
     * 存放字典项
     * @param dictItemBean 字典实体
     */
    default void putDictItem(DictItemBean dictItemBean) {
        StaticDictPool.putDictItem(this, dictItemBean);
    }

    /**
     * 获取字典实体
     * @return 字典实体
     */
    default DictItemBean getDictBean() {
        return StaticDictPool.getDictItem(this);
    }

    /**
     * 获取类目名称
     * @return 类目名称
     */
    default String category() {
        return getDictBean().getCategory();
    }

    /**
     * 返回字典单项英文名
     * @return 返回字典单项英文名
     */
    default String item() {
        return getDictBean().getItem();
    }

    /**
     * 返回字典单项中文标签
     * @return 返回字典单项中文标签
     */
    default String itemLabel() {
        return getDictBean().getItemLabel();
    }

    /**
     * 返回字典单项值
     * @return 返回字典单项值
     */
    default String itemValue() {
        return getDictBean().getItemValue();
    }

    /**
     * 返回字典单项值（int）
     * @return 返回字典单项值（int）
     */
    default int itemIntValue() {
        return toInt(getDictBean().getItemValue(), -1);
    }

    /**
     * 返回字典单项值（List）
     * @return 返回字典单项值（List）
     */
    default List<String> itemListValue() {
        return StrUtil.split(getDictBean().getItemValue(), ",",true,true);
    }

    /**
     * 判定单项值
     * @param value
     * @return 布尔
     */
    default boolean isItemValue(String value) {
        return StrUtil.isNotBlank(value) && value.endsWith(itemValue());
    }

    /**
     * 获取枚举
     * @param enumClass enumClass
     * @param itemValue itemValue
     * @param defaultEnum defaultEnum
     * @param <E> e
     * @return Enum
     */
    static <E extends Enum<E>> E getEnum(final Class<?> enumClass, final String itemValue, E defaultEnum) {
        E[] enumConstants = (E[])enumClass.getEnumConstants();
        return Arrays.stream(enumConstants).filter(p -> ((IDictItem)p).itemValue().equals(itemValue)).findFirst().orElse(defaultEnum);
    }

    /**
     * 获取枚举
     * @param enumClass enumClass
     * @param item itemValue
     * @param defaultEnum defaultEnum
     * @param <E> e
     * @return Enum
     */
    static <E extends Enum<E>> E getEnumAtItem(final Class<?> enumClass, final String item, E defaultEnum) {
        E[] enumConstants = (E[])enumClass.getEnumConstants();
        return Arrays.stream(enumConstants).filter(p -> ((IDictItem)p).item().equalsIgnoreCase(item)).findFirst().orElse(defaultEnum);
    }

    /**
     * 获取枚举标签值
     * @param enumClass enumClass
     * @param itemValue itemValue
     * @param defaultItemLabel defaultItemLabel
     * @param <E>
     * @return
     */
    static <E extends Enum<E>> String getEnumItemLabel(final Class<E> enumClass, final String itemValue, String defaultItemLabel) {
        E enumObject = getEnum(enumClass, itemValue, null);
        if(null == enumObject) {
           return defaultItemLabel;
        }
        return ((IDictItem)enumObject ).itemLabel();
    }


    public static Integer toInteger(Object o, Integer defVal) {
        if (o == null) {
            return defVal;
        }
        if (o instanceof String) {
            try {
                return Integer.parseInt((String) o);
            } catch (final NumberFormatException nfe) {
                return defVal;
            }
        }
        if (o instanceof byte[]) {
            byte[] res = (byte[]) o;
            if (res.length == 4) {
                return (res[0] & 0x00ff) | ((res[1] << 8) & 0xff00) | ((res[2] << 24) >>> 8) | (res[3] << 24);
            }
        }
        if (o instanceof Number) {
            return ((Number) o).intValue();
        }
        return defVal;
    }

    /**
     * <p>Convert a <code>String</code> to an <code>int</code>, returning a
     * default value if the conversion fails.</p>
     *
     * <p>If the string is <code>null</code>, the default value is returned.</p>
     *
     * <pre>
     *   NumberUtils.toInt(null, 1) = 1
     *   NumberUtils.toInt("", 1)   = 1
     *   NumberUtils.toInt("1", 0)  = 1
     * </pre>
     *
     * @param o  the string to convert, may be null
     * @param defVal  the default value
     * @return the int represented by the string, or the default if conversion fails
     */
    public static int toInt(Object o, int defVal) {
        return toInteger(o, defVal);
    }
}
